var running = false;
var socket = io.connect('http://localhost');

socket.on('toclient', function (data)
{
    log_entry("<span class='info'>"+data.clientlog+"</span>")
});

socket.on('hoover_output', function (data)
{
    log_entry(data.clientlog)
});

socket.on('disconnect', function (data)
{
    $('#error_msg').html('Disconnected from server. Please refresh this page.');
    $('#error').css('display', 'block');
});

//-----------------------------
// Disconnect on page unload
//-----------------------------
window.onunload = function()
{
    socket.disconnect();
};

//-----------------------------
// Changing between normal and replay modes
//-----------------------------
function toggle_replay()
{
    $(".mode").toggle('fast');
}

//-----------------------------
// Changing between logging formats
//-----------------------------
function toggle_log_format()
{
    $('#lverbose_available').toggle('fast', function() {$('#lunaltered_available').toggle('fast')});
}

//-----------------------------
// Toggle fuzzing setup visibility
//-----------------------------
function toggle_fuzzing()
{
    $("#fuzzing_setup").toggle('fast');
    $("#fuzzers").toggle('fast');
}

//-----------------------------
// Responding to a y/n question
//-----------------------------
function respond(answer) 
{
    $('#question').css('display', 'none');
    log_entry("<span class='sent'>Sending: '"+ answer +"'</span>");
    socket.emit('command', { msg: answer });
}

//-----------------------------
// Log to the #log div element
//-----------------------------
function log_entry(msg)
{
    console.log(msg);
    msg = msg.replace(/\n/g, '<br>');

    $('#log').append( msg+"<br>" );
    var div = $('#log');
    div.scrollTop( div.get(0).scrollHeight );
}

//-----------------------------
// After hoover has shutdown etc
//----------------------------
function restore_config()
{
    $("#hooverbtn").button('option', 'label', 'Start Hoover');
    running = false;
    $(".controlbtn").prop('disabled', true).button("refresh");
    $(".config").prop('disabled', false);
}

//-----------------------------
// Executed when the page has finished loading
//-----------------------------
$(function()
{

    list_saved_settings();
    $("#tabs").tabs();

    //-----------------------------
    // Firefox messes up the inputs with AC
    //-----------------------------
    $('input').attr('autocomplete', 'off');
    $('select').attr('autocomplete', 'off');
    $('button').attr('autocomplete', 'off');

    $("#dostuff").click( function() 
    {
        log_entry("<span class='sent'>Sending '"+ $("#cmd").val() +"'</span>");
        socket.emit('command', { msg: $('#cmd').val() });
    });

    //-----------------------------
    // Get available interfaces 
    //-----------------------------
    log_entry("<span class='sent'>Fetching available interfaces!</span>");
    socket.emit('command', { msg: "interfaces" });

    socket.on('interfaces', function (data)
    {
        log_entry("<span class='info'>Interface: "+data.interfaces+"</span>");
        $("#inputinterfaces").append('<option value="'+data.interfaces+'">'+data.interfaces+'</option>');
        $("#outputinterfaces").append('<option value="'+data.interfaces+'">'+data.interfaces+'</option>');
        $("#hooverbtn").prop('disabled', false).button("refresh"); 
    });

    //-----------------------------
    // Get available fuzzers
    //-----------------------------
    log_entry("<span class='sent'>Fetching available fuzzers!</span>");
    socket.emit('command', { msg: "fuzzers" });

    socket.on('fuzzers', function (data)
    {
        log_entry("<span class='info'>Fuzzer: "+data.fuzzers+"</span>");
        if (data.fuzzers == 'None') {
            //log_entry("Skipping None fuzzer...");
            return;
        }

        $("#fuzzers").append('<div class="checkbox_container"><input type="checkbox" class="config" name="fuzzers" value="'+data.fuzzers+'">'+data.fuzzers+"</div>");
    });

    //---------------------------------
    // Start / Stop Hoover toggle button
    //---------------------------------
    $("#hooverbtn").click( function()
    {
        if (running == false) {

            var chosen_fuzzers = [];
            $("input:checkbox[name=fuzzers]:checked").each(function()
            {
                chosen_fuzzers.push($(this).val());
            });

            var chosen_drops = [];
            $("input:checkbox[name=drop]:checked").each(function()
            {
                chosen_drops.push($(this).val());
            });

            //---------------------------------
            // Verify fuzzing probability
            //---------------------------------
            var fprobability = $("#fprobability").val();
            if (chosen_fuzzers.length > 0 && (!$.isNumeric(fprobability) || fprobability < 1 || fprobability > 100)
                && !(chosen_fuzzers.length == 1 && $("input:checkbox[value=Duplicate]").prop('checked'))) // Duplicate fuzzer is not really a fuzzer 
            {
                //log_entry('Error: Fuzzing probability needs to be between 1% and 100%!');
                $('#error_msg').html('Fuzzing probability needs to be between 1% and 100%!');
                $('#error').css('display', 'block');
                return;            
            }

            //---------------------------------
            // Verify duplicating probability
            //---------------------------------
            var duplicate = $("#duplicate").val();
            if ((!$.isNumeric(duplicate) || duplicate < 1 || duplicate > 100)
                && $("input:checkbox[value=Duplicate]").prop('checked')) {
                //log_entry('Error: duplicate probability needs to be between 1% and 100%!');
                $('#error_msg').html('Duplicate probability needs to be between 1% and 100%!');
                $('#error').css('display', 'block');
                return;            
            }

            //---------------------------------
            // Verify timer value
            //---------------------------------
            var timer = $("#ftimer").val();
            if (timer.length > 0 && (!$.isNumeric(timer) || timer < 1)) {
                $('#error_msg').html('Invalid timer value!');
                $('#error').css('display', 'block');
                return;            
            }

            //---------------------------------
            // Verify replay setup
            //---------------------------------
            if ($("#replay option:selected").val() == 1) {

                var tmp = $("#replay_from").val();
                if (tmp.length < 1) {
                    //log_entry('Error: no replay file defined');
                    $('#error_msg').html('No replay file defined!');
                    $('#error').css('display', 'block');
                    return;
                }

                var replay_interval = $("#replay_interval").val();
                if (replay_interval.length > 0 && (!$.isNumeric(replay_interval) || replay_interval < 1)) {
                    //log_entry('Error: replay interval needs to be a positive numbers');
                    $('#error_msg').html('Replay interval needs to be a positive number!');
                    $('#error').css('display', 'block');
                    return;            
                }
            }

            fprobability = fprobability / 100;
            duplicate = duplicate / 100;

            log_entry("<span class='sent'>Sending start command!</span>");

            //---------------------------------
            // Spawn hoover!
            //---------------------------------
            socket.emit('command', {
                    msg: "hoover_start",
                    proxy: $("#proxy").val(),
                    outputif: $("#outputinterfaces option:selected").val(),
                    inputif: $("#inputinterfaces option:selected").val(),
                    fuzzing_enabled: $("#fuzzing_enabled option:selected").val(),
                    fuzzers: chosen_fuzzers,
                    drops: chosen_drops,
                    fprobability: fprobability,
                    duplicate: duplicate,
                    flevel: $("#flevel").val(),
                    ftimer: $("#ftimer").val(),
                    loutput: $("#loutput").val(),
                    lformat: $("#lformat").val(),
                    lverbose: $("#lverbose").val(),
                    lunaltered: $("#lunaltered").val(),
                    flt_protocol: $("#flt_protocol option:selected").val(),
                    flt_ipsrc: $("#flt_ipsrc").val(),
                    flt_ipdst: $("#flt_ipdst").val(),
                    flt_srcport: $("#flt_srcport").val(),
                    flt_dstport: $("#flt_dstport").val(),
                    s_ipsrc: $("#s_ipsrc").val(),
                    s_ipdst: $("#s_ipdst").val(),
                    s_ip6src: $("#s_ip6src").val(),
                    s_ip6dst: $("#s_ip6dst").val(),
                    s_ethsrc: $("#s_ethsrc").val(),
                    s_ethdst: $("#s_ethdst").val(),
                    replay: $("#replay option:selected").val(),
                    replay_interval: replay_interval,
                    replay_from: $("#replay_from").val(),
                    fuzzing_options: $("#fuzzing_options").val(),
                    settings_from_file: $("#settings_from_file").val()
              });

            $("#hooverbtn").button('option', 'label', 'Stop Hoover');
            running = true;
            $(".controlbtn").prop('disabled', false).button("refresh");
            $(".config").prop('disabled', true);

        } else {
            log_entry("<span class='sent'>Sending stop command!</span>");
            socket.emit('command', { msg: "hoover_stop" });
            //-----------------------------
            // Lets wait a bit before restoring config again
            //-----------------------------
            //setTimeout(restore_config(), 600);
        }
    });

    //---------------------------------
    // Runtime control buttons
    //---------------------------------
    $("#swap").click( function()
    {
        log_entry("<span class='sent'>Sending swap command!</span>");
        socket.emit('command', { msg: "s" });
    });

    $("#packetdetails").click( function()
    {
        log_entry("<span class='sent'>Sending packet information command!</span>");
        socket.emit('command', { msg: "i" });
    });

    $("#changefuzzer").click( function()
    {
        log_entry("<span class='sent'>Sending fuzzer change command!</span>");
        socket.emit('command', { msg: "f" });
    });

    $("#settings").click( function()
    {
        log_entry("<span class='sent'>Sending help/settings command!</span>");
        socket.emit('command', { msg: "h" });
    });

    $("#timer").click( function()
    {
        log_entry("<span class='sent'>Sending timer command!</span>");
        socket.emit('command', { msg: "t" });
    });

    $("button").button();

    //-----------------------------
    // On hoover shutdown
    //-----------------------------
    socket.on('hoover_shutdown', function (data)
    {
        log_entry("<span class='info'>"+data.clientlog+"</span>");
        //-----------------------------
        // Lets wait a bit before restoring config again
        //-----------------------------
        setTimeout(restore_config(), 600);
    });

    //-----------------------------
    // On error
    //-----------------------------
    socket.on('error', function (data)
    {
        log_entry(data.msg);
        $('#error_msg').html(data.msg);
        $('#error').css('display', 'block');
    });

    //-----------------------------
    // Log file issue with [y/n]
    //-----------------------------
    socket.on('log_output_msg', function (data)
    {
        log_entry(data.msg);
        $('#question_msg').html(data.msg);
        $('#question').css('display', 'block');
    });

});

//-----------------------------
// Save form state to the localStorage
//-----------------------------
function save() {

    if ($('#settings_title').val().length < 1) {
        return;
    }

    var titles = [];
    var saved_settings = {};
    var updating = true;

    if (localStorage.titles !== undefined) {
        titles = JSON.parse(localStorage.titles);
    }

    if (localStorage.saved_settings !== undefined) {
        saved_settings = JSON.parse(localStorage.saved_settings);
    }

    var title = $('#settings_title').val();

    if (titles.indexOf(title) == -1) {
        titles.push(title);
        updating = false;
    }

    localStorage.titles = JSON.stringify(titles);

    var append = {};

    append[title] = $("#master_form").serialize();

    $.extend(true, saved_settings, append);

    if (updating == false) {
        add_load_entry(title);
    }

    localStorage.saved_settings = JSON.stringify(saved_settings);

    $('#info_msg').html('Current settings have been saved as <i>'+title+'</i>!');
    $('#info').css('display', 'block');
}

//-----------------------------
// Restore form state from the localStorage
//-----------------------------
function restore_save(title) {

    //-----------------------------
    // Save current state of the GUI
    //-----------------------------
    var replay_mode_before = $("#replay option:selected").val();
    var fuzzing_enabled_before = $("#fuzzing_enabled option:selected").val();
    var lformat_before = $("#lformat option:selected").val();

    //-----------------------------
    // Restore the saved state
    //-----------------------------
    if (localStorage.titles !== undefined) {
        titles = JSON.parse(localStorage.titles);
    }

    if (localStorage.saved_settings !== undefined) {
        saved_settings = JSON.parse(localStorage.saved_settings);
    }

    $("#master_form").unserializeForm(saved_settings[title], {
        'override-values' : true
      });

    //--------------------------------
    // Update the GUI
    //--------------------------------
    if ($("#replay option:selected").val() != replay_mode_before) {
        toggle_replay();
    }

    if ($("#fuzzing_enabled option:selected").val() != fuzzing_enabled_before) {
        toggle_fuzzing();
    }

    if ($("#lformat option:selected").val() != lformat_before) {
        toggle_log_format();
    }

    $('#info_msg').html('Setting <i>'+title+'</i> has been restored!');
    $('#info').css('display', 'block');
}

//-----------------------------
// List saved states in the localStorage
//-----------------------------
function list_saved_settings() {

    if (localStorage.titles == undefined) {
        return;
    }

    titles = JSON.parse(localStorage.titles);

    for (var i in titles) {
        add_load_entry(titles[i]);
    }
}

//-----------------------------
// Add a Load settings entry
//-----------------------------
function add_load_entry(title) {
    $("#storage_settings_load").append('<option value="'+title+'">'+title+'</option>');
    $("#storage_settings_delete").append('<option value="'+title+'">'+title+'</option>');
}

//-----------------------------
// Delete a Load entry
//-----------------------------
function delete_save(title) {
    var titles = [];
    var saved_settings = {};

    if (localStorage.titles !== undefined) {
        titles = JSON.parse(localStorage.titles);
    }

    if (localStorage.saved_settings !== undefined) {
        saved_settings = JSON.parse(localStorage.saved_settings);
    }

    titles.splice(titles.indexOf(title), 1);
    delete saved_settings[title];
    $("#storage_settings_load option[value='"+title+"']").remove();
    $("#storage_settings_delete option[value='"+title+"']").remove();

    localStorage.titles = JSON.stringify(titles);
    localStorage.saved_settings = JSON.stringify(saved_settings);

    $('#info_msg').html('Saved setting <i>'+title+'</i> has been deleted!');
    $('#info').css('display', 'block');
}

//-----------------------------
// Delete all Load entries
//-----------------------------
function delete_load_entries() {
    localStorage.clear();
    $("#storage_settings_load").html('');
    $("#storage_settings_delete").html('');

    $('#info_msg').html('All saved settings have been deleted!');
    $('#info').css('display', 'block');
}


  
